﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Prisa.Entities;
using System.Data;
using Microsoft.Practices.Unity;
using System.Data.SqlClient;
using System.Data.Objects;

namespace Prisa.DataAccess
{
    public class HistorialVentaDAO:MasterDataAccess , IHistorialVentaDAO
    {
        public List<HISTORIAL_VENTAS> GetAllFromHistorialVentas()
        {
            var hoy = DateTime.Today.Date;

            var query = from h in Context.HISTORIAL_VENTAS.Include("PRODUCTO")
                        //where h.Fecha == hoy
                        orderby h.Fecha descending
                        select h;

            ObjectContext.Refresh(RefreshMode.ClientWins, query);

            return query.ToList();
        }

        public List<HISTORIAL_VENTAS> GetFromHistorialVentasbyFechasAndProductoAndContado(DateTime? fec1, DateTime? fec2, string producto, bool contado)
        {
            if (producto != "") // si hay descripcion de producto
            {
                var query = from h in Context.HISTORIAL_VENTAS.Include("PRODUCTO")
                            where h.Contado == contado
                            select h;
                
                if (fec1 != null && fec2 != null)//ventas por rango de fechas
                {
                    query = from h in query
                            where (h.Fecha >= fec1.Value && h.Fecha <= fec2.Value) &&
                                    h.PRODUCTO.Descripcion.ToUpper().Contains(producto.ToUpper())
                            select h;
                    
                    ObjectContext.Refresh(RefreshMode.StoreWins, query);

                }
                if (fec1 != null && fec2 == null)//ventas por dia
                {
                    query = from h in query
                            where h.Fecha == fec1.Value &&
                                h.PRODUCTO.Descripcion.ToUpper().Contains(producto.ToUpper())
                            select h;
                    
                    ObjectContext.Refresh(RefreshMode.StoreWins, query);

                }
                
                return query.ToList();
            }
            else  // si descripcion esta vacio o no coincide la busqueda
            {
                var query = from h in Context.HISTORIAL_VENTAS.Include("PRODUCTO")
                            where h.Contado == contado
                            select h;
                

                if (fec1 != null && fec2 != null)//ventas por rango de fechas
                {
                    query = from h in query
                            where (h.Fecha >= fec1.Value && h.Fecha <= fec2.Value)
                            select h;
                    
                    ObjectContext.Refresh(RefreshMode.StoreWins, query);

                }
                if (fec1 != null && fec2 == null)//ventas por dia
                {
                    query = from h in query
                            where h.Fecha == fec1.Value
                            select h;

                    ObjectContext.Refresh(RefreshMode.StoreWins, query);
                }

                return query.ToList();
            }
        }

        public List<HISTORIAL_VENTAS> GetFromHistorialVentasbyFechasAndProductoAndCredito(DateTime? fec1, DateTime? fec2, string producto, bool credito)
        {
            if (producto != "") // si hay descripcion de producto
            {
                var query = from h in Context.HISTORIAL_VENTAS.Include("PRODUCTO")
                            where h.Credito == credito
                            select h;

                if (fec1 != null && fec2 != null)//ventas por rango de fechas
                {
                    query = from h in query
                            where (h.Fecha >= fec1.Value && h.Fecha <= fec2.Value) &&
                                    h.PRODUCTO.Descripcion.ToUpper().Contains(producto.ToUpper())
                            select h;

                    ObjectContext.Refresh(RefreshMode.StoreWins, query);

                }
                if (fec1 != null && fec2 == null)//ventas por dia
                {
                    query = from h in query
                            where h.Fecha == fec1.Value &&
                                h.PRODUCTO.Descripcion.ToUpper().Contains(producto.ToUpper())
                            select h;

                    ObjectContext.Refresh(RefreshMode.StoreWins, query);
                }
                
                return query.ToList();
            }
            else  // si descripcion esta vacio o no coincide la busqueda
            {
                var query = from h in Context.HISTORIAL_VENTAS.Include("PRODUCTO")
                            where h.Credito == credito
                            select h;

                if (fec1 != null && fec2 != null)//ventas por rango de fechas
                {
                    query = from h in query
                            where (h.Fecha >= fec1.Value && h.Fecha <= fec2.Value)
                            select h;

                    ObjectContext.Refresh(RefreshMode.StoreWins, query);

                }
                if (fec1 != null && fec2 == null)//ventas por dia
                {
                    query = from h in query
                            where h.Fecha == fec1.Value
                            select h;

                    ObjectContext.Refresh(RefreshMode.StoreWins, query);

                }
                
                return query.ToList();
            }
        }

        public List<HISTORIAL_VENTAS> GetFromHistorialVentasbyFechasAndProductoAndMenudeo(DateTime? fec1, DateTime? fec2, string producto, bool menudeo)
        {
            if (producto != "") // si hay descripcion de producto
            {
                var query = from h in Context.HISTORIAL_VENTAS.Include("PRODUCTO")
                            where h.Menudeo == menudeo
                            select h;

                if (fec1 != null && fec2 != null)//ventas por rango de fechas
                {
                    query = from h in query
                            where (h.Fecha >= fec1.Value && h.Fecha <= fec2.Value) &&
                                    h.PRODUCTO.Descripcion.ToUpper().Contains(producto.ToUpper())
                            select h;
                    ObjectContext.Refresh(RefreshMode.StoreWins, query);

                }
                if (fec1 != null && fec2 == null)//ventas por dia
                {
                    query = from h in query
                            where h.Fecha == fec1.Value &&
                                h.PRODUCTO.Descripcion.ToUpper().Contains(producto.ToUpper())
                            select h;
                    ObjectContext.Refresh(RefreshMode.StoreWins, query);

                }
                if (fec1 == null && fec2 == null)//ventas por dia
                {
                    query = from h in query
                            where h.PRODUCTO.Descripcion.ToUpper().Contains(producto.ToUpper())
                            select h;

                    ObjectContext.Refresh(RefreshMode.StoreWins, query);

                }
                return query.ToList();

            }
            else  // si descripcion esta vacio o no coincide la busqueda
            {
                var query = from h in Context.HISTORIAL_VENTAS.Include("PRODUCTO")
                            where h.Menudeo == menudeo 
                            select h;
                
                if (fec1 != null && fec2 != null)//ventas por rango de fechas
                {
                    query = from h in query
                            where (h.Fecha >= fec1.Value && h.Fecha <= fec2.Value)
                            select h;
                    ObjectContext.Refresh(RefreshMode.StoreWins, query);

                }
                if (fec1 != null && fec2 == null)//ventas por dia
                {
                    query = from h in query
                            where h.Fecha == fec1.Value
                            select h;
                    ObjectContext.Refresh(RefreshMode.StoreWins, query);

                }
                return query.ToList();
            }
        }

        public HISTORIAL_VENTAS GetFromHistorialVentasById(int id)
        {
            var query = from hv in Context.HISTORIAL_VENTAS
                        where hv.Id.Equals(id)
                        select hv;
            
            ObjectContext.Refresh(RefreshMode.StoreWins, query);

            return query.SingleOrDefault();
        }

        public void AddHistorialVentas(HISTORIAL_VENTAS historialVenta)
        {            
            Context.HISTORIAL_VENTAS.Add(historialVenta); 
            Context.SaveChanges();
        }

        public void UpdateHistorialVenta(int idProducto, DateTime? fecha, Decimal precio, int cantidadAct, int nuevaCant)
        {
            var existe = (from hv in Context.HISTORIAL_VENTAS
                          where
                          hv.Contado == true &&
                          hv.ProductoId == idProducto &&
                          hv.Fecha == fecha &&
                          hv.Precio == precio &&
                          hv.Cantidad == cantidadAct
                          select hv).FirstOrDefault();
            

            if (existe != null)
            {
                existe.Cantidad = nuevaCant;
                existe.Total = precio * nuevaCant;
                Context.Entry(existe).State = EntityState.Modified;
                Context.SaveChanges();
            }
        }

        public void UpdateHistorialCredito(int idProducto, DateTime? fecha, Decimal precio, int cantidadAct, int nuevaCant)
        {
            var existe = (from hv in Context.HISTORIAL_VENTAS
                          where
                          hv.Credito == true &&
                          hv.ProductoId == idProducto &&
                          hv.Fecha == fecha &&
                          hv.Precio == precio &&
                          hv.Cantidad == cantidadAct
                          select hv).FirstOrDefault();

            if (existe != null)
            {
                existe.Cantidad = nuevaCant;
                existe.Total = precio * nuevaCant;
                Context.Entry(existe).State = EntityState.Modified;
                Context.SaveChanges();
            }
        }
        
        public void RemoveHistorialVentas(int idProducto, DateTime? fecha, Decimal precio, int cantidad)
        {
            var existe = (from hv in Context.HISTORIAL_VENTAS
                         where 
                         hv.Contado == true &&
                         hv.ProductoId == idProducto && 
                         hv.Fecha == fecha && 
                         hv.Precio == precio && 
                         hv.Cantidad == cantidad
                         select hv).FirstOrDefault();

            if (existe != null)
            {
                Context.HISTORIAL_VENTAS.Remove(existe);
                Context.SaveChanges();
            }
        }

        public void RemoveHistorialCredito(int idProducto, DateTime? fecha, decimal precio, int cantidad)
        {
            var existe = (from hv in Context.HISTORIAL_VENTAS
                          where
                          hv.Credito == true &&
                          hv.ProductoId == idProducto &&
                          hv.Fecha == fecha &&
                          hv.Precio == precio &&
                          hv.Cantidad == cantidad
                          select hv).FirstOrDefault();
            
            if (existe != null)
            {
                Context.HISTORIAL_VENTAS.Remove(existe);
                Context.SaveChanges();
            }
        }

        public void CierreDeCaja(DateTime? FechaHistorial)
        {
            if (FechaHistorial != null)
            {
                var parmFecha = new SqlParameter("@fechaHistorial", FechaHistorial.Value);
                Context.Database.ExecuteSqlCommand("CIERREdeCAJA @fechaHistorial", parmFecha);
            }
        }

        public bool GetAllHistorialByProductoId(int idProducto)
        {
            var venta = from cr in Context.DETALLEVENTAs.Include("PRODUCTO")
                        where cr.ProductoId.Equals(idProducto)
                        select cr;

            var credito = from cr in Context.DETALLE_CREDITO.Include("PRODUCTO")
                        where cr.ProductoId.Equals(idProducto)
                        select cr;

            var compra = from cr in Context.DETALLECOMPRAs.Include("PRODUCTO")
                        where cr.ProductoId.Equals(idProducto)
                        select cr;

            var query = from c in Context.HISTORIAL_VENTAS.Include("PRODUCTO")
                        where c.ProductoId.Equals(idProducto)
                        select c;

            return venta.Any() || credito.Any() ||compra.Any()  ||query.Any();
        }

        public void UpdateHistorialMenudeo(HISTORIAL_VENTAS historialMenudeo)
        {
            Context.HISTORIAL_VENTAS.Attach(historialMenudeo);
            Context.Entry(historialMenudeo).State = EntityState.Modified;
            Context.SaveChanges();
        }
    }
}
